<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2021/4/26} {9:45} 
 */

namespace wanghua\general_utility_tools_php\es;


use wanghua\general_utility_tools_php\Date;
use wanghua\general_utility_tools_php\tool\Tools;

/**
 * @deprecated 废弃，即将删除
 *
 * 【es原生操作库】
 * 【仅支持框架ThinkPHP5+、 PHP7.2+】
 *
 * BaseElasticsearch.php类库的替代库
 *
 * 使用步骤：
 * 初始化（设置ip、索引前缀-普通索引请设置为空字符串）
 * 设置索引范围（例如查询本月，如果索引不是按日期规律设置，请使用普通索引设置方法setIndexNormal，并设置前缀为空字符串）
 * 设置查询方法（eg: _search）
 * 设置查询参数（查询条件）
 * 执行
 * 返回结果
 * Class ElasticsearchUtility
 * @package app\admin\logic
 */
class Elasticsearch
{
    protected $es_log_file = 'es_log';
    //最终拼装的请求地址
    protected $post_url = ''; //eg: $url = 'http://49.4.3.4:9111/qa-item-2021.04/_search';
    //查询参数
    protected $query_param = [];
    //查询方法
    protected $query_method = '_search';
    //文档索引
    protected $index = '';
    //服务器ip
    protected $ip = '';
    //索引前缀(优先设置)
    protected $index_sign = '';//eg: qa-stat-
    //设置查询日期格式符号
    protected $doc_date_sign = '.';
    //设置是哪个方法调用本es库，用于日志记录
    protected $exe_func = '';


    /**
     * ElasticsearchUtility constructor.
     * @param string $ip_port 协议+服务器ip+端口号，必须
     * @param string $index_sign 当es索引为有规律的日期索引时，可使用前缀并配合日期索引设置方法，体验更佳
     */
    public function __construct(string $ip_port, string $index_sign='')
    {
        $this->ip = false===strpos($ip_port,'http')?'http://'.$ip_port:$ip_port;
        $this->index_sign = $index_sign;
    }

    /**
     * desc：设置查询方法，默认_search
     * author：wh
     * @param $method_name
     */
    function setQueryMethod($method_name){
        $this->query_method = $method_name;
    }


    /**
     * desc：根据日期索引查询文档
     * 注：默认一个月
     *
     * eg:'qa-stat-2021.01';
     *
     * 注：如果es设置的索引没有规律也不是日期作为索引，请设置普通索引setIndexNormal，且请在初始化时，设置索引前缀index_sign为""字符串
     * author：wh
     */
    function setIndexDefault(){
        $this->setRequestIndex(date('Y'.$this->doc_date_sign.'m'));
    }

    /**
     * desc：设置要查询的日期文档索引
     *
     * 1、按年检索文档[建议5年左右]
     *
     * eg: qa-stat-2018.*,qa-stat-2019.*,qa-stat-2020.*,qa-stat-2021.*
     *
     *  注意：当索引过长，es会抛出索引太长异常
     *
     * 注：如果es设置的索引没有规律也不是日期作为索引，请设置普通索引setIndexNormal，且请在初始化时，设置索引前缀index_sign为""字符串
     *
     * author：wh
     * @param string $start_time 开始时间 eg：2010-01-01 08:05:55
     * @param string $end_time 结束时间 eg：2021-12-31 12:05:00
     * @return string
     */
    function setIndexYearDate(string $start_time, string $end_time){

        //默认查询索引
        $index = date('Y'.$this->doc_date_sign.'*', strtotime($start_time));

        $sign = ',';//分隔符

        $m = date('Y', strtotime($end_time)) - date('Y', strtotime($start_time));

        //拼装查询索引
        for ($i=0; $i<$m; $i++){

            $index .= $sign.($this->index_sign.(date('Y', strtotime($start_time))+$i).$this->doc_date_sign.'*');
        }

        $this->setRequestIndex($index);
    }

    /**
     * desc：设置日期索引
     *
     * 检索全部日期索引文档
     *
     * 例如es设置的索引为：
     *  qa-stat-2021.01
        qa-stat-2021.02
        qa-stat-2021.03
        qa-stat-2021.04
     *
     * 实际查询自动设置为：qa-stat-*
     *
     * 注：如果es设置的索引没有规律也不是日期作为索引，请设置普通索引setIndexNormal，且请在初始化时，设置索引前缀index_sign为""字符串
     *
     * author：wh
     * @return string
     */
    function setIndexAllDate(){

        $this->setRequestIndex('*');
    }

    /**
     * desc：设置普通索引
     *
     * 调用此方法，请在初始化时，设置索引前缀index_sign为""空字符串
     *
     * author：wh
     * @param string $index
     */
    function setIndexNormal(string $index){
        $this->setRequestIndex($index);
    }

    /**
     * desc：设置跨月份索引
     *
     * eg: qa-stat-2021.01,qa-stat-2021.02
     *
     * 注：如果es设置的索引没有规律也不是日期作为索引，请设置普通索引setIndexNormal，且请在初始化时，设置索引前缀index_sign为""字符串
     *
     * author：wh
     * @param string $start_time eg:'2020-11'
     * @param string $end_time eg:'2021-01'
     * @return string eg: qa-stat-2020.11,qa-stat-2020.12,qa-stat-2021.01
     */
    function setIndexDate(string $start_time, string $end_time){
        $date = new Date();

        //计算月份
        $m = $date->dateCutMonth($start_time, $end_time);
        ////解决跨年且不足1个月时，索引设置错误问题
        //if($m == 0 && (date('Y', strtotime($end_time)) > date('Y', strtotime($start_time)))){
        //    $m = 1;
        //}
        //格式
        $date->date_format = 'Y-m';

        //默认查询索引
        $index = date('Y'.$this->doc_date_sign.'m', strtotime($start_time));

        $tmp_time = $start_time;
        $sign = ',';//分隔符

        //拼装查询索引
        for ($i=0; $i<$m; $i++){
            $tmp_time = $date->addTime(1, 'M', strtotime($tmp_time));
            $index .= $sign.$this->index_sign.(date('Y'.$this->doc_date_sign.'m', strtotime($tmp_time)));
        }

        $this->setRequestIndex($index);
    }


    /**
     * desc：设置查询参数
     * author：wh
     * @param string $query_param_json
     */
    function setQueryParam(string $query_param_json){
        $this->query_param = $query_param_json;
        $this->post_url = $this->ip.'/'.$this->index.'/'.$this->query_method;
    }

    /**
     * desc：获取查询参数，用于调试
     * author：wh
     * @return array
     */
    function getQueryParam(){
        return [
            'ip'=>$this->ip,
            'index_sign'=>$this->index_sign,
            'index'=>$this->index,
            'query_method'=>$this->query_method,
            'post_url'=>$this->post_url,
            'query_param'=>$this->query_param,
        ];
    }

    /**
     * desc：执行es查询
     * author：wh
     * @return array|bool|int|string
     * @throws \Exception
     */
    function execute(){
        if(empty($this->ip)) throw new \Exception('请设置ip');
        //if(empty($this->index_sign)) throw new \Exception('请设置索引前缀');
        if(empty($this->index)) throw new \Exception('请设置索引');
        if(empty($this->query_method)) throw new \Exception('请设置查询方法');
        if(empty($this->query_param)) throw new \Exception('请设置查询参数');




        Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'request_url'=>$this->post_url,'IN'=>" | IN: ",'query_params'=>$this->query_param, 'input'=>input()], $this->es_log_file);
        $result = Tools::curl_post($this->post_url, $this->query_param);
        Tools::log_to_write_txt(['exe_func'=>$this->exe_func,'OUT'=>" | OUT: ", 'result'=>$result], $this->es_log_file);

        return $result;
    }

    /**
     * desc：设置是哪个方法调用本es库，用于日志记录
     * author：wh
     * @param string $function
     */
    function setExecuteFunction(string $function){
        $this->exe_func = $function;
    }

    /**
     * desc：设置请求文档索引
     * author：wh
     * @param string $index
     */
    protected function setRequestIndex(string $index){
        $this->index = $this->index_sign.$index;
    }

}